#ifndef __OPTIM_PROBLEM_H__
#define __OPTIM_PROBLEM_H__

#include <deque>
#include <sstream>
#include <string>
#include "type_def.h"

class OptimizerState;

struct OptimProblem {
	virtual double eval(const DVector& x, DVector& gradient) = 0;
};

struct TerminationCriterion {
	virtual double GetValue(const OptimizerState& state, std::ostream& message) = 0;
	virtual ~TerminationCriterion() {
	}
};

class RelativeMeanImprovementCriterion: public TerminationCriterion {
	const int numItersToAvg;
	std::deque<double> prevVals;

public:
	RelativeMeanImprovementCriterion(int numItersToAvg = 5) :
			numItersToAvg(numItersToAvg) {
	}

	double GetValue(const OptimizerState& state, std::ostream& message);
};

#endif // __OPTIM_PROBLEM_H__
